//#include "core_cm0.h"
#ifndef __PRONANO_H__
#define __PRONANO_H__

#include <stdio.h>
#include <stdint.h>
#include <DrvSYS.h>
#include <DrvUART.h>
#include <DrvGPIO.h>
#include <DrvFMC.h>
#include <DrvI2C.h>
#include <DrvPWM.h>
#include <DrvSPI.h>
#include <DrvTimer.h>
#include <DrvADC.h>
#include <math.h>
#include <DrvUSB.h>

#define RTC_Power_ADC 1   //take use of GPA.7, RTC volt ADC
#define USE_BSP_ver_June_2011 1  //backward compatible to ver 2010

#ifdef USE_BSP_ver_June_2011

//redefine identifiers in DrvSYS.h
#define SYSTICK_CLKSOURCE SysTick_CTRL_CLKSOURCE_Pos
#define SYSTICK_ENABLE SysTick_CTRL_ENABLE_Pos
#define DrvSYS_GetHCLK() DrvSYS_GetHCLKFreq()/1000  //Get HCLK in kHz

//redefine identifiers in DrvGPIO.h
#define FUNC_GPIO E_FUNC_GPIO
#define DrvSYS_SetHCLKSource DrvSYS_SelectHCLKSource
#define GPB E_GPB
#define GPC E_GPC
#define GPE E_GPE
#define GPA E_GPA
#define IO_INPUT E_IO_INPUT
#define IO_OUTPUT E_IO_OUTPUT
#define IO_FALLING E_IO_FALLING
#define MODE_EDGE E_MODE_EDGE
#define IO_RISING E_IO_RISING
#define DBCLKSRC_10K E_DBCLKSRC_10K
#define FUNC_I2C0 E_FUNC_I2C0
#define FUNC_PWM01 E_FUNC_PWM01

//redefine identifiers in DrvUART.h
#define FUNC_UART0 E_FUNC_UART0
#define FUNC_UART1 E_FUNC_UART1
#define FUNC_UART2 E_FUNC_UART2


//redine identifiers in DrvFMC.h

//redefine identifiers in DrvI2C.h
#define DrvI2C_EnableTimeoutCount DrvI2C_SetTimeoutCounter

//redefine idedentifiers in DrvPWM.h
#define DRVPWM_TOGGLE_MODE DRVPWM_AUTO_RELOAD_MODE

//redefin identifiers in DrvSPI.h
#define DrvSPI_SetClock DrvSPI_SetClockFreq

//redefin identifiers in NUC1xx.h
#define SPI1_SS0 SPI1_SS0_MCLK

//redefin identifiers in DrvTIMER.c & DrvTimer.h
#define DrvTIMER_GetTicks DrvTIMER_GetIntTicks
#define DrvTIMER_ResetTicks DrvTIMER_ResetIntTicks
#define TMR2 E_TMR2
#define TMR0 E_TMR0
#define PERIODIC_MODE E_PERIODIC_MODE

//redefine identifiers in DrvADC.c & DrvADC.h
#define EXT_12MHZ EXTERNAL_12MHZ

//redefine identifiers in DrvUSB.h
#define IEF_WAKEUP INTEN_WAKEUP
#define IEF_FLD INTEN_FLDET
#define IEF_USB INTEN_USB
#define IEF_BUS INTEN_BUS

#endif  //USE_BSP_ver_June_2011

//#define ProNano_Fit_Mode 1
#ifdef ProNano_Fit_Mode  //fitting process

#define DEBUG_INFO_PORT UART_PORT0
#define TFT_COMM_PORT UART_PORT1
#define DEBUG_INFO_PORT_ID 0
#define TFT_COMM_PORT_ID 1

#else  //release process

#define DEBUG_INFO_PORT UART_PORT2
#define DEBUG_INFO_PORT_ID 2
#define PRINTER_PORT UART_PORT0
#define TFT_COMM_PORT UART_PORT1
#define PRINTER_PORT_ID 0
#define TFT_COMM_PORT_ID 1

#endif  //macro ProNano_Fit_Mode

//data flash
#define DATA_FLASH_PAGESIZE 512
#define FLASH_SIZE 128*1024
//#define DATA_FLASH_BASE 0x0001F000
#define DATA_FLASH_BASE (FLASH_SIZE-10*3*DATA_FLASH_PAGESIZE-DATA_FLASH_PAGESIZE)  //0x1D600//0x1C200
#define METADATA_FLASH_BASE (FLASH_SIZE-DATA_FLASH_PAGESIZE)
#define PARAM_FLASH_BASE (DATA_FLASH_BASE-0x200-0x200)  //0x1BE00~0x1C200 total 1k bytes, storing params for this machine
#define USE_DATA_FLASH 1
#define VersionID       0x1a2b3c4d

#define SYS_DEBUG 1
//#define LCD_DEBUG 1
//#define FLASH_DEBUG 1
#define APP_DEBUG 1
#define ProNano_DEBUG 1
//#define Dump_Dvalid_CNR_DEBUG 1
#define MBI5170_DEBUG 1

/*To keep phase alignment between g_DDC114_CONV_Freq & g_XenonFrequency, must set...
g_DDC114_CONV_Freq is equal to power of 2
g_XenonFrequency is equal to power of 2
integral Xenon pulse periods=g_XenonFrequency/(2*g_DDC114_CONV_Freq)
//DDC114 CONV period=1/(2*DDC114_CONV_Freq)=1562.5(us)
//total time to tranfer 80 bit ADC data=(1/SPI_Clock)*80
*/
#define DDC114_CONV_Freq 320
#define SPI_Clock 400000
#define LED562_ON DrvGPIO_SetBit(GPC, 6);  //LEDEN1, active high
#define LED562_OFF DrvGPIO_ClrBit(GPC, 6);
#define LED595_ON DrvGPIO_SetBit(GPC, 15);
#define LED595_OFF DrvGPIO_ClrBit(GPC, 15);
#define LED660_ON DrvGPIO_SetBit(GPA, 0);
#define LED660_OFF DrvGPIO_ClrBit(GPA, 0);

void Init_console(void);
void Init_Interface_IO(void);
void ProNano_Init(void);
void SysTimerDelay(uint32_t us);
char Get_key_queue(int enable_screen_saving);
void Put_key_Queue(char key);
void Show_logo(int start_up);
int is_RTC_Low_Power(void);
void Display_Assay_Page(void);
void Display_Measurement_Page(void);
void Display_Main_Menu_Page(void);
void Delay100ms(int a);
void Delay10ms(int a);
int is_Power_Down();
void Update_sheet_index(int cur_sheet, int head_sheet, int tail_sheet) ;


/*20130417 added by michael, brand control
our own brand define no any XXX_ODM macro
white brand: define macro DEF_ODM without any customer brand qualifier
vendor specific ODM: define macro DEF_ODM with any other qualifier macro <Vendeo_ODM>
*/

//#define DEF_ODM 1
//#define KASVI_ODM 1
//#define LOCCUS_ODM 1
//#define TIANGEN_ODM 1

//#define Delay100ms(a) SysTimerDelay(a*100*1000*1000)
//#define Delay10ms(a) SysTimerDelay(a*10*1000*1000)

/* kb define */
#define Enter_key 0x0d
#define Up_key  'w'
#define Down_key  'x'
#define Power_key 'a'
#define Null_key 0x00
#define Refresh_key 'r'

/*scren saving mode timeout seconds*/
#define Timeout_Screen_Saving 30

#define USE_KEY_QUEUE 1
#define MAX_keys   30
#define MAX_Sheets 10
#define MAX_Page_Sheets 7

extern char buf2[100];
extern int menu_index, Assay_index;
extern int cur_sheet, head_sheet, tail_sheet, Select_sheet;
extern volatile uint8_t bPrinter_status, bPrinter_error, bPrinter_warning;

struct PackedDate {
						unsigned int Second: 6;		// 0..59

						// higher 32 bits
                        unsigned int Minute : 6;    // 0..59                       63 is reserved as EOD marker
                        unsigned int Hour : 5;      // 0..23                       31 is reserved as EOD marker
                        unsigned int Day : 5;       // 1..31
                        unsigned int Month : 4;     // 1..12
                        unsigned int Year : 12;		// 0..4095
                                             
                    };

// 8 byte (64 bit) date time stamp
union MaestroDate
{
  char Date[5];
  struct PackedDate PackDate;
};

struct Measure_data {
  double Xenon_I, Non_Xenon_I;
};

#define MAX_Samples 30

struct Measure_sheet {
	int sheet_type;
	union MaestroDate sheet_date;
};

struct Measure_tran {
    int sheet_type;
	union MaestroDate sheet_date;
	int blank_flag, sample_index;
	//  struct Measure_data blank, samples_A230[MAX_Samples], samples_A260[MAX_Samples], samples_A280[MAX_Samples];
	struct Measure_data blank_AXXX, samples_AXXX;
	double AXXX[MAX_Samples];
	union MaestroDate date[MAX_Samples+1];
	int sample_No[MAX_Samples];
	int last_sample_No;
	int err_status;
	unsigned char check_digits[8];
};

/*struct ProNano_Flash_t {
	int sheet_type;
	union MaestroDate sheet_date;
	int blank_flag, sample_index;
	struct Measure_data blank_AXXX, samples_AXXX;
	double AXXX[MAX_Samples];
	union MaestroDate date[MAX_Samples+1];
	int sample_No[MAX_Samples];
	unsigned char check_digits[8];
}; //4+5+8+8*6+8*3*30+31*5+4*30*/

int Add_measurement(struct Measure_tran *pMea_tran, int type) ;
void Display_measure_output1(struct Measure_tran *pMea_tran, int type, int sample_index); //type: 0,blank; type: 1,BCA; type: 2,Bradford; type: 3,Pierce
void Show_LCD_IMG(const unsigned char img[][12], int digit, int x, int y);
int Del_measurement(struct Measure_tran *pMea_tran, int sample_index);
void Display_Time_Setup();
int Store_sheet(struct Measure_tran *pMea_tran, int type, struct Measure_sheet *pSheet, int sheet_index); //type: 0,blank; type: 1,BCA; type: 2,Bradford; type: 3,Pierce
int Load_sheet(struct Measure_tran *pMea_tran, struct Measure_sheet *pSheet, int sheet_index); //type: 0,blank; type: 1,BCA; type: 2,Bradford; type: 3,Pierce
void Display_Show_And_Print_Page();
void Show_and_Print();
void UART_INT_HANDLE(uint32_t u32IntStatus);
int Print_Selected(struct Measure_tran *pMea_tran, int *pIndex, struct Measure_sheet *pSheet);
void Set_Maestro_RTC(union MaestroDate *pDate, int index);
void Get_Maestro_RTC(union MaestroDate *pDate, int index) ;
void Time_Setup();
void TMR_Callback();
void TMR_Callback2();
void I2C0_Callback_Tx(uint32_t status);
void I2C0_Timeout(uint32_t status);
void Led_Current_Sink_On(int LED_index);
void Led_Current_Sink_Off();
void Setting_up_CC(int index, int lower_CC, int upper_CC);
void MaestroNano_Capture(int phase, int samples);

/* I2C RTC device */
#define M41T0_I2C_Slave_Addr 0x68
/* Tx_Data0={An, length, byte0, ...}, An is word address, then follow by data */
extern uint8_t Tx_Data0[10];
extern uint8_t Rx_Data0[10];
extern uint8_t DataLen0;
extern volatile uint8_t EndFlag0, start_I2C;
extern volatile uint32_t refresh_time;
extern volatile uint8_t MBI5170_CC_562nm, MBI5170_CC_595nm, MBI5170_CC_660nm;

#define I_Led_562 100000
#define I_Led_595 100000
#define I_Led_660 100000
#define Led_562_fail 1 
#define Led_595_fail 1 << 1
#define Led_660_fail 1 << 2

/*20130515 added by michael
MBI5170 SPI*/
#define Led_driver_SDI 6  //PA.6
#define Led_driver_MOD 5  //PA.5
#define Led_driver_CLK 4  //PA.4
#define Led_driver_OE 3  //PA.3

/*20130522 added by michael
define the target intensity*/
#define I_Led562_target 500000
#define I_Led595_target 650000
#define I_Led660_target 600000

//struct for dos fat table & directory entry
struct dir_entry {
  char Filename[8];
  char Extension[3];
  char Attributes;
  char NTRes;
  char CrtTimeTenth;
  short CrtTime;
  short CrtDate;
  short LstAccDate;
  short FstClusHI;
  short WrtTime;
  short WrtDate;
  short FstClusLO;
  long FileSize;
};

#define Printer_test 1

/*20130613 added by michael*/
#define WAIT_CTS_ASSERT \
					while (1) { \
					  DrvUART_GetCTSInfo(PRINTER_PORT, &pu8CTSValue, &pu8CTSChangeState); \
					  if (!pu8CTSValue) \
                         break; \
					}
#endif  //__PRONANO_H__
